package com.cskaoyan.javase.oop3._2inner._4local._1basic;

/**
 * 分析:
 *      1.局部内部类定义在类的局部位置,作用范围被局部位置的作用域限制死了
 *          所以局部内部类成员的访问
 *          仅限于外围类装有局部内部类的作用域内部
 *          外围类的其他位置访问不到
 *          外部类肯定访问不到
 *       2.局部内部类仍然是内部类,所以它和外围类也是好兄弟,但是情况发生了一些变化
 *          局部内部类访问外围类仍然不受权限限制
 *          但是外围类必须在作用域内部才能够访问到这个局部内部类,也不受权限限制
 *              外围类其他位置访问不到了.
 *
 * 局部内部类的访问特点:
 * 局部内部类的访问特点，我们仍然主要从以下几个角度研究：
 * 这里我们以方法中的局部内部类为例
 * 但是外围类的成员方法和静态方法中的局部内部类是不同的:
 * 局部内部类访问外围类成员:
 *      1.成员方法中的局部内部类
 *          会隐含持有外围类对象的引用
 *          用"外围类类名.this"指向外围类对象
 *
 *          访问:
 *              局部内部类内部访问外围类
 *              可以直接访问外围类成员
 *              如果出现同名,用this等区分即可.
 *              这里的使用和成员内部类类似
 *
 *      2.静态成员方法中的局部内部类
 *          静态方法没有对象,也不会让局部内部类对象
 *          隐含持有外围类对象的引用
 *
 *          访问:
 *              创建外围类对象,然后访问
 *
 *  2.外围类访问局部内部类成员
 *      只能在作用域内部创建对象访问
 *      也不受权限限制
 *      但是其他位置都无法访问了
 *
 *  3.外部类访问局部内部类成员
 *      不能,访问不到了,因为局部内部类已经隐藏了
 *      访问不到这个局部内部类
 *      但是可以通过方法返回值,返回这个局部内部类对象的成员
 *          甚至也可以把这个局部内部类对象给返回出来
 *          但是局部内部类是没办法访问的
 *
 *  4.局部内部类访问外部类成员
 *      可以,创建对象即可,受权限限制.
 *
 *
 * @since 14:47
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        EnclosedClazz ec = new EnclosedClazz();
        ec.test();

        EnclosedClazz.testStatic();
    }
}

class EnclosedClazz {
    int a;
    private int b = 10;
    static int c = 20;
    static final int D = 30;

    public void test() {
        // 这个方法的局部变量a访问不到
        int a = 10;
        class Inner {
            int a = 10;
            private int b = 20;
            {
                a = 100;
            }
            public void testInner(int a) {
                System.out.println(a);
                System.out.println(this.a);
                System.out.println(EnclosedClazz.this.a);
                System.out.println(b);
            }

            public Inner() {
                System.out.println("hello world!");
            }
        }
        Inner i = new Inner();
        System.out.println(i.a);
        System.out.println(i.b);

    }

    public static void testStatic() {
        class Inner {
            public void testInner() {
                // System.out.println(a);
                // System.out.println(b);
                EnclosedClazz ec = new EnclosedClazz();
                System.out.println(ec.a);
                System.out.println(ec.b);
            }
        }
        Inner inner = new Inner();
        System.out.println(inner);
    }
}